﻿using SMS.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SMS.Domain.Concrete.Mapping;
using System.Data.Entity.Infrastructure;

namespace SMS.Domain.Concrete
{
    //todo:Mirar la colección de errores en la clase EntityValidationErrors
    public class EFDbContext : DbContext
    {
        #region DbSet Miembros.
        
        public DbSet<Reto> Retos { get; set; }
        public DbSet<Respuesta> Respuestas { get; set; }
        public DbSet<RespuestaValoracion> RespuestaValoraciones { get; set; }
        public DbSet<Categoria> Categorias { get; set; }
        //public DbSet<User> Users { get; set; }
        public DbSet<UserSMS> UsersSMS { get; set; }
        public DbSet<UserOng> UsersOng { get; set; }
        public DbSet<Ong> Onges { get; set; }
        public DbSet<OngDelegacion> OngDelegaciones { get; set; }
        
        #endregion
        
        #region DbContext Override
        
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //Añadimos la configuración por medio de fluent API utilizando la propiedad Configuration
            modelBuilder.Configurations.Add(new UserSMSEntityTypeConfiguration());
            modelBuilder.Configurations.Add(new CategoriaEntityTypeConfiguration());
            modelBuilder.Configurations.Add(new OngDelegacionEntityTypeConfiguration());
            modelBuilder.Configurations.Add(new RespuestaEntityTypeConfiguration());
            modelBuilder.Configurations.Add(new RespuestaValoracionEntityTypeConfiguration());
            modelBuilder.Configurations.Add(new RetoEntityTypeConfiguration());
            modelBuilder.Configurations.Add(new UserOngEntityTypeConfiguration());
            //esta linea elimina el "on delete cascade" por defecto en la creacion del modelo
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        }

        public override int SaveChanges()
        {
            //Sobreescribimos el método SaveChanges para almacenar los campos de auditoría.
            //todo: Quitar lo de carga. Cuando se dan de alta los usuario, no se almacena los campos de au
            var auditUser="Carga";
            if (System.Web.HttpContext.Current !=null )
                //Todo: Mirar ha obtener el userid para guardarlo en el campo de auditoría.
                auditUser = System.Web.HttpContext.Current.User.Identity.Name;
            DateTime auditDate = DateTime.UtcNow;
            foreach (DbEntityEntry<Auditable> entry in ChangeTracker.Entries<Auditable>())
            {
                if (entry.State == System.Data.EntityState.Added)
                {
                    entry.Entity.CreateUserById = auditUser;
                    entry.Entity.CreateDate = auditDate;
                }
                else if (entry.State == System.Data.EntityState.Modified)
                {
                    entry.Entity.UpdateUserById = auditUser;
                    entry.Entity.UpdateDate = auditDate;
                }
            }
            
            return base.SaveChanges();
        }
        #endregion
    }
    
}
